(function () {
  //暴露Bird小鸟的构造函数
  var Bird = window.Bird = function () {
    //从中介者game类中取得bird的图片资源
    //定义小鸟颜色图片的随机数，一共就三个颜色所以随机0 - 3，拿这个随机数去game类中的数组中拿到指定的颜色的小鸟，字符串拼接这个数字就能得到随机的url
    this.imgrandom = parseInt(Math.random() * 3);  //随机色小鸟
    this.imgArr = [
      //咱们定义的imgrandom随机数决定了用哪个颜色的小鸟，字符串拼接
      game.imgS["bird" + this.imgrandom + "_0"],  //上飞姿态图
      game.imgS["bird" + this.imgrandom + "_1"],  //平飞姿态图
      game.imgS["bird" + this.imgrandom + "_2"],  //往下掉落姿态图
    ];
    this.width = this.imgArr[0].width;  //小鸟的图片大小
    this.height = this.imgArr[0].height;  //小鸟图片的宽
    //定义小鸟的翅膀煽动的步数：其实就是每一次的更新都会改变三张图片的状态，上 中 下
    this.step = 0;
    //定义小鸟的初始x位置  , 最后得-自己的宽度
    this.x = myCanvas.width * (1 - 0.718) - 24;
    //定义小鸟的初始y位置,起始改变鸟的位置就是改变y的坐标，坐标系移动鸟的y坐标，鸟就会下降下升
    this.y = 100;
    //定义小鸟的帧数
    this.fno = 0;
    //定义小鸟的旋转角度
    this.deg = 0;
    //定义小鸟的飞行状态
    this.hasEnergy = false;
    this.birdSpeed = 0;
  };
  //小鸟的渲染
  Bird.prototype.render = function () {
    //保存坐标系
    game.ctx.save();
    //改变坐标系就能改变鸟的绘制的x y点，这样就能产生鸟的飞 和 下降,起始位置是x y
    game.ctx.translate(this.x, this.y);
    //旋转坐标系
    game.ctx.rotate(this.deg);
    //小鸟此时的左上角在坐标系的中心，所以要讲小鸟移动到坐标系中心，移动负的自身宽和高
    game.ctx.drawImage(this.imgArr[this.step], -this.width / 2, -this.height / 2);
    //恢复坐标系
    game.ctx.restore();
    //碰撞盒定义和计算：需要在坐标系平移和旋转之前计算，因为需要和管子的计算在一个坐标系
    //每一次的渲染都得计算小鸟AABB碰撞盒,小鸟的图片是一张48 X 48的图片，小鸟的碰撞盒是一个矩形，矩形得减去空白部分，因为撞到空白部分不算是碰撞。 坐标系移动到了bird的 X和y，小鸟又移动自身的宽度和高度将自己的中心点移动到了坐标系，也就是说小鸟的图片中心点是bird的X和y，从中心年出发计算矩形的四条边的位置
    //坐标系移动到了小鸟的x 和 y，小鸟图片又位移自身宽度 高度的一半，所以小鸟图片的中心点现在位移this.x 和 this.y，
    //从this.x 和this.y这个图片中心点出发计算测量出小鸟的碰撞盒四条边，左右边根据X来，上下边根据Y来
    this.T = this.y - 11; //小鸟碰撞盒的上边T的位置就是this.y + 11
    this.B = this.y + 13; //小鸟的碰撞盒下边B的位置就是
    this.L = this.x - 6;
    this.R = this.x + 14;
    //开发者模式：AABB碰撞盒测试
    // game.ctx.strokeRect(this.x - 15, this.T, 33, 1); //上碰撞线
    // game.ctx.strokeRect(this.x - 15, this.B, 33, 1); //下碰撞线
    // game.ctx.strokeRect(this.R, this.y - this.height / 2, 1, 42); //右碰撞线
    // game.ctx.strokeRect(this.L, this.y - this.height / 2, 1, 42);  //左碰撞线

  };
  //小鸟的更新  
  Bird.prototype.update = function () {
    //如果失去飞行能量下落算法
    if (!this.hasEnergy) {
      //下落速度Y增加：增加的值根据自己的帧数来计算 乘以 一个比例
      this.birdSpeed++;
      this.y += this.birdSpeed * 0.4;  //鸟的y加上鸟的速度，就会加速度往下掉
      this.deg += 0.037;     //旋转角度 ++
    } else {
      this.birdSpeed-=1.47;  //如果有能量上升状态，鸟的速度下降
      this.y -= this.birdSpeed * 0.1;   //改变y 负的方向的话鸟就上向上绘制一段距离
//小鸟有能量的时候这行这个代码，也要进行一次判断:20帧之后小鸟失去飞行能量
      if (this.birdSpeed <= 0) { //16 - 0绘制长度
        this.hasEnergy = false;   //如果速度到达0了，那么小鸟重新失去能量重新变成掉落状态
      }
    }


  };
   //小鸟每次的fly方法
  Bird.prototype.fly = function () {
    //小鸟每次的fly方法会向上飞,得到飞行能量
    this.hasEnergy = true;
    this.deg = -0.6;  //角度回到向上
    this.fno = 0;   //bird对象的帧信息回到：也就是加速度回到0初始的速度
    this.birdSpeed = 38;
  };
  //单独封装小鸟的煽动翅膀的方法符合低耦合。咱们开始界面也得让小鸟煽动翅膀。煽动翅膀就是改变三张图片,
  Bird.prototype.wings = function () {
    //每一此更新update,翅膀状态, 进行判断，每10帧改变一次小鸟的图片:如果 fno帧数能被 10取余，那就煽动一次翅膀（换一张状态图片）
    game.fno % 10 == 0 && this.step++;
    //小鸟状态图片一共就3个，步长大于等于3回到0
    if (this.step > 2) {
      this.step = 0;
    }
  }


})();